#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define isoctal(x) ( '0' <= (x) && (x) < '8' )
#define ishexa(x) ( isdigit(x) || 'a' <= tolower(x) && tolower(x) <= 'f')

#include "tokens.h"

extern FILE *tape;
char lexeme[32];
double lexval;

isID()
{
    int head = getc(tape);
    if (isalpha(head)) {
	int p = 0;
	lexeme[p++] = head;
	while (isalnum(head = getc(tape)))
	    p < 31 && (lexeme[p++] = head);
	lexeme[p] = 0;
	ungetc(head, tape);
	return ID;
    }
    ungetc(head, tape);
    return 0;
}

isNUM()
{
    int head = getc(tape);
    if (isdigit(head)) {
	int p = 0;
	if (head == '0') {
	    lexeme[0] = head;
	    lexeme[1] = 0;
	    lexval = 0;
	    return NUM;
	}
	lexeme[p++] = head;
	while (isdigit(head = getc(tape)))
	    (p < 10) && (lexeme[p++] = head);
	ungetc(head, tape);
	lexeme[p] = 0;
	lexval = atof(lexeme);
	return NUM;
    }
    ungetc(head, tape);
    return 0;
}

gettoken()
{
    /** tape head */
    int head;
    /** temporary token **/
    int token;
    /** skip spaces **/
    while (isspace(head = getc(tape)))
	if (head == '\n')
	    return '\n';
    ungetc(head, tape);
    /** try each automaton next **/
    if (token = isID(tape))
	return token;
    if (token = isNUM(tape))
	return token;
    lexeme[1] = 0;
    return lexeme[0] = getc(tape);
}

/** parser interface hereafter */

int lookahead;

void match(int expected)
{
    if (lookahead == expected) {
	lookahead = gettoken();
    } else {
	fprintf(stderr, "token mismatch: found %d but %d expected\n", lookahead, expected);
	exit(-1);
    }
}